#include "os_sal.h"


/* os queue 消息队列 */


/* export func */


#if (CONFIG_OS_ENABLE == 1)

#if defined(CONFIG_OS_TYPE_FREERTOS)

#include "FreeRTOS.h"
#include "queue.h"


/**
 * @brief OS创建消息队列
 * 
 * @param items 队列数量
 * @param size 每队列大小
 * @return os_queue_handle_t 队列句柄
 */
os_queue_handle_t os_queue_create(uint32_t items, uint32_t size)
{
	os_queue_handle_t queue;

	queue = xQueueCreate(items, size);

	return queue;
}

/**
 * @brief OS删除消息队列
 * 
 * @param queue 队列句柄
 * @return os_status_t 
 */
os_status_t os_queue_delete(os_queue_handle_t queue)
{
	if (queue == NULL) return OS_STA_ERROR;
	vQueueDelete(queue);
	return OS_STA_SUCCESS;
}

/**
 * @brief OS发送消息队列
 * 
 * @param queue 队列句柄
 * @param msg 消息
 * @param waittime 发送等待时钟节拍
 * @return os_status_t 
 */
os_status_t os_queue_send(os_queue_handle_t queue, void *msg, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (queue == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xQueueSendFromISR(queue, msg, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xQueueSend(queue, msg, waittime);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}

/**
 * @brief OS接收消息队列
 * 
 * @param queue 队列句柄
 * @param msg 消息接收缓存
 * @param waittime 接收等待时钟节拍
 * @return os_status_t 
 */
os_status_t os_queue_receive(os_queue_handle_t queue, void *msg, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (queue == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xQueueReceiveFromISR(queue, msg, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xQueueReceive(queue, msg, waittime);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}

/**
 * @brief OS消息队列重置
 * 
 * @param queue 队列句柄
 * @return os_status_t 
 */
os_status_t os_queue_reset(os_queue_handle_t queue)
{
	BaseType_t err;
	os_status_t os_sta;

	if (queue == NULL) return OS_STA_ERROR; 

	err = xQueueReset(queue);
	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}



#else
    #error "CONFIG_OS_TYPE not support!"
#endif // CONFIG_OS_TYPE

#endif // CONFIG_OS_ENABLE


